package com.zhiwen.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhiwen.common.api.Result;
import com.zhiwen.domain.dto.CommentDTO;
import com.zhiwen.domain.entity.Comment;
import com.zhiwen.service.CommentService;
import com.zhiwen.domain.vo.CommentCountVO;
import com.zhiwen.domain.vo.CommentVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 评论控制器
 */
@Tag(name = "评论管理", description = "评论相关接口")
@RestController
@RequiredArgsConstructor
@RequestMapping("/comments")
public class CommentController {

    private final CommentService commentService;

    /**
     * 创建评论
     *
     * @param commentDTO 评论数据
     * @return 评论视图对象
     */
    @Operation(summary = "创建评论", description = "对回答发表评论，需要登录")
    @SecurityRequirement(name = "Authorization")
    @ApiResponse(responseCode = "200", description = "创建成功",
                content = @Content(schema = @Schema(implementation = CommentVO.class)))
    @SaCheckLogin
    @PostMapping
    public Result<CommentVO> createComment(@Validated @RequestBody CommentDTO commentDTO) {
        CommentVO commentVO = commentService.createComment(commentDTO);
        return Result.success(commentVO);
    }

    /**
     * 更新评论
     *
     * @param id 评论ID
     * @param commentDTO 评论数据
     * @return 评论视图对象
     */
    @Operation(summary = "更新评论", description = "更新已有评论，需要登录且只有创建者可以更新")
    @SecurityRequirement(name = "Authorization")
    @ApiResponse(responseCode = "200", description = "更新成功",
                content = @Content(schema = @Schema(implementation = CommentVO.class)))
    @SaCheckLogin
    @PutMapping("/{id}")
    public Result<CommentVO> updateComment(
            @Parameter(description = "评论ID") @PathVariable Long id,
            @Validated @RequestBody CommentDTO commentDTO) {
        commentDTO.setId(id);
        CommentVO commentVO = commentService.updateComment(commentDTO);
        return Result.success(commentVO);
    }

    /**
     * 获取评论详情
     *
     * @param id 评论ID
     * @return 评论视图对象
     */
    @Operation(summary = "获取评论详情", description = "获取指定评论的详细信息")
    @ApiResponse(responseCode = "200", description = "获取成功",
                content = @Content(schema = @Schema(implementation = CommentVO.class)))
    @GetMapping("/{id}")
    public Result<CommentVO> getComment(@Parameter(description = "评论ID") @PathVariable Long id) {
        CommentVO commentVO = commentService.getCommentById(id);
        return Result.success(commentVO);
    }

    /**
     * 删除评论
     *
     * @param id 评论ID
     * @return 成功标志
     */
    @Operation(summary = "删除评论", description = "删除已有评论，需要登录且只有创建者可以删除")
    @SecurityRequirement(name = "Authorization")
    @ApiResponse(responseCode = "200", description = "删除成功")
    @SaCheckLogin
    @DeleteMapping("/{id}")
    public Result<Void> deleteComment(@Parameter(description = "评论ID") @PathVariable Long id) {
        commentService.deleteComment(id);
        return Result.success();
    }

    /**
     * 批量删除指定回答下的所有评论
     *
     * @param answerId 回答ID
     * @return 删除的评论数量
     */
    @Operation(summary = "批量删除回答下的评论", description = "批量删除指定回答下的所有评论，需要管理员权限")
    @SecurityRequirement(name = "Authorization")
    @Parameter(name = "answerId", description = "回答ID")
    @ApiResponse(responseCode = "200", description = "删除成功")
    @SaCheckRole("admin")
    @DeleteMapping("/answer/{answerId}")
    public Result<Integer> batchDeleteByAnswerId(@PathVariable Long answerId) {
        int count = commentService.batchDeleteByAnswerId(answerId);
        return Result.success(count);
    }

    /**
     * 获取回答的评论分页列表
     *
     * @param answerId 回答ID
     * @param current 当前页
     * @param size 每页大小
     * @return 评论分页列表
     */
    @Operation(summary = "获取回答的评论列表", description = "分页获取指定回答下的评论列表")
    @Parameters({
        @Parameter(name = "answerId", description = "回答ID"),
        @Parameter(name = "current", description = "当前页码", schema = @Schema(defaultValue = "1")),
        @Parameter(name = "size", description = "每页数量", schema = @Schema(defaultValue = "10"))
    })
    @ApiResponse(responseCode = "200", description = "获取成功")
    @GetMapping("/answer/{answerId}")
    public Result<Page<CommentVO>> getCommentPage(
            @PathVariable Long answerId,
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size) {
        Page<Comment> page = new Page<>(current, size);
        Page<CommentVO> commentPage = commentService.getCommentPage(answerId, page);
        return Result.success(commentPage);
    }

    /**
     * 获取当前用户的所有评论
     *
     * @param current 当前页
     * @param size 每页大小
     * @return 评论分页列表
     */
    @Operation(summary = "获取当前用户的评论列表", description = "分页获取当前登录用户的所有评论，需要登录")
    @SecurityRequirement(name = "Authorization")
    @Parameters({
        @Parameter(name = "current", description = "当前页码", schema = @Schema(defaultValue = "1")),
        @Parameter(name = "size", description = "每页数量", schema = @Schema(defaultValue = "10"))
    })
    @ApiResponse(responseCode = "200", description = "获取成功")
    @SaCheckLogin
    @GetMapping("/my")
    public Result<Page<CommentVO>> getMyComments(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size) {
        Page<Comment> page = new Page<>(current, size);
        Long userId = StpUtil.getLoginIdAsLong();
        Page<CommentVO> commentPage = commentService.getUserComments(userId, page);
        return Result.success(commentPage);
    }

    /**
     * 获取最新评论列表
     *
     * @param limit 限制数量
     * @return 最新评论列表
     */
    @Operation(summary = "获取最新评论列表", description = "获取系统中最新的评论列表")
    @Parameter(name = "limit", description = "获取条数，默认为10，最大50", schema = @Schema(defaultValue = "10"))
    @ApiResponse(responseCode = "200", description = "获取成功")
    @GetMapping("/latest")
    public Result<List<CommentVO>> getLatestComments(
            @RequestParam(defaultValue = "10") Integer limit) {
        List<CommentVO> comments = commentService.getLatestComments(limit);
        return Result.success(comments);
    }

    /**
     * 获取评论统计信息
     *
     * @return 评论统计信息
     */
    @Operation(summary = "获取评论统计信息", description = "获取系统评论总数和用户评论数")
    @SecurityRequirement(name = "Authorization")
    @ApiResponse(responseCode = "200", description = "获取成功")
    @SaCheckLogin
    @GetMapping("/count")
    public Result<CommentCountVO> getCommentCount() {
        Long userId = StpUtil.getLoginIdAsLong();
        CommentCountVO countVO = commentService.getCommentCount(userId);
        return Result.success(countVO);
    }

    /**
     * 管理员获取所有评论
     *
     * @param answerId 回答ID (可选)
     * @param current 当前页
     * @param size 每页大小
     * @return 评论分页列表
     */
    @Operation(summary = "管理员获取所有评论", description = "管理员分页获取所有评论，可选择指定回答ID")
    @SecurityRequirement(name = "Authorization")
    @Parameters({
        @Parameter(name = "answerId", description = "回答ID(可选)"),
        @Parameter(name = "current", description = "当前页码", schema = @Schema(defaultValue = "1")),
        @Parameter(name = "size", description = "每页数量", schema = @Schema(defaultValue = "10"))
    })
    @ApiResponse(responseCode = "200", description = "获取成功")
    @SaCheckRole("admin")
    @GetMapping("/admin")
    public Result<Page<CommentVO>> getAllComments(
            @RequestParam(required = false) Long answerId,
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size) {
        Page<Comment> page = new Page<>(current, size);
        Page<CommentVO> commentPage = commentService.getAllComments(answerId, page);
        return Result.success(commentPage);
    }
}
